package com.jiaolong.service;

import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradePrecreateModel;
import com.alipay.api.domain.BusinessParams;
import com.alipay.api.domain.ExtendParams;
import com.alipay.api.domain.GoodsDetail;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradePrecreateRequest;
import com.alipay.api.response.AlipayTradePrecreateResponse;
import com.jiaolong.config.AlipayConfig;
import com.jiaolong.dto.OrderDto;
import com.jiaolong.dto.PaymentRequestDto;
import com.jiaolong.utils.CreMchOrderNoUtil;
import com.jiaolong.utils.QRConfigUtil;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.util.HashMap;
import java.util.Iterator;

@Service
public class AlipayService {

    @Resource
    private AlipayConfig alipayConfig;

    @Resource
    private OrderService orderService;

    /**
     * 付款码支付
     * @param dto
     * @param servletResponse
     */
    public void paymentCode(PaymentRequestDto dto, HttpServletResponse servletResponse) {
        // 1.初始化SDK
        AlipayClient alipayClient = new DefaultAlipayClient(alipayConfig.getServerUrl(), alipayConfig.getAppId(), alipayConfig.getAppPrivateKey(),
                alipayConfig.getFormat(), alipayConfig.getCharset(), alipayConfig.getAlipayPublicKey(), alipayConfig.getSignType());

        // 2.构造请求参数以调用接口
        AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();
        AlipayTradePrecreateModel model = new AlipayTradePrecreateModel();

        // 3.设置商户门店编号
        model.setStoreId("JL_001");

        // 设置业务扩展参数
        ExtendParams extendParams = new ExtendParams();
        extendParams.setSysServiceProviderId("2088511833207846");
        extendParams.setSpecifiedSellerName("跨境小铺");
        extendParams.setCardType("S0JP0000");
        model.setExtendParams(extendParams);

        // 设置订单标题
        model.setSubject(dto.getSubject());

        // 设置商户订单号 (支付时传入的商户订单号，与 trade_no 必填一个)
        model.setOutTradeNo(dto.getMchOrderNo());

        // 设置订单金额
        model.setTotalAmount(dto.getAmount().toString());

        // 设置商户操作员编号
        model.setOperatorId("jl_001");

        // 设置卖家支付宝用户ID
        model.setSellerId("2088721035348681");

        request.setBizModel(model);
        try {
            AlipayTradePrecreateResponse response = alipayClient.execute(request);
            System.out.println(response.getBody());

            if (response.isSuccess()) {
                System.out.println("调用成功");
            } else {
                System.out.println("调用失败");
                // sdk版本是"4.38.0.ALL"及以上,可以参考下面的示例获取诊断链接
                // String diagnosisUrl = DiagnosisUtils.getDiagnosisUrl(response);
                // System.out.println(diagnosisUrl);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 扫码支付
     * @param dto
     * @param servletResponse 用户选择使用支付宝时需要传入此参数用来返回二维码信息，当使用蛟龙支付时，传入null即可
     * @return content 支付跳转地址
     */
    public String payScanCode(OrderDto dto, HttpServletResponse servletResponse) {
        // 初始化SDK
        AlipayClient alipayClient = new DefaultAlipayClient(alipayConfig.getServerUrl(), alipayConfig.getAppId(), alipayConfig.getAppPrivateKey(),
                alipayConfig.getFormat(), alipayConfig.getCharset(), alipayConfig.getAlipayPublicKey(), alipayConfig.getSignType());

        // 构造请求参数以调用接口
        AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();

        // 设置请求回调地址
        request.setNotifyUrl(alipayConfig.getNotifyUrl());

        AlipayTradePrecreateModel model = new AlipayTradePrecreateModel();

        // 设置商户门店编号
        model.setStoreId("JL_001");

        // 设置业务扩展参数
        ExtendParams extendParams = new ExtendParams();
        extendParams.setSysServiceProviderId("2088511833207846");
        extendParams.setSpecifiedSellerName("蛟龙支付支付宝沙箱测试");
        extendParams.setCardType("S0JP0000");
        model.setExtendParams(extendParams);

        // 设置订单标题
        model.setSubject(dto.getTitle());

        // 支付订单过期时间
//        model.setTimeExpire("1m");

        // 设置商户操作员编号
        model.setOperatorId(dto.getMacNo());

        // 设置产品码
        model.setProductCode("FACE_TO_FACE_PAYMENT");

        // 设置订单附加信息
        model.setBody(dto.getTitle());

        // 设置订单包含的商品列表信息
        List<GoodsDetail> goodsDetail = new ArrayList<GoodsDetail>();
        GoodsDetail goodsDetail0 = new GoodsDetail();
        goodsDetail0.setGoodsName("ipad");
        goodsDetail0.setQuantity(1L);
        goodsDetail0.setPrice("2000");
        goodsDetail0.setGoodsId("apple-01");
        goodsDetail0.setGoodsCategory("34543238");
        goodsDetail0.setCategoriesTree("124868003|126232002|126252004");
//        goodsDetail0.setShowUrl(alipayConfig.getNotifyUrl());
//        goodsDetail.add(goodsDetail0);
//        model.setGoodsDetail(goodsDetail);

        // 设置商户的原始订单号
        model.setMerchantOrderNo("20161008001");

        // 设置可打折金额
        //model.setDiscountableAmount("80.00");

        // 设置商户订单号
        model.setOutTradeNo(dto.getMchOrderNo());

        // 设置订单总金额
        model.setTotalAmount(dto.getAmount().toString());

        // 设置商户传入业务信息
        BusinessParams businessParams = new BusinessParams();
        businessParams.setMcCreateTradeIp("127.0.0.1");
        model.setBusinessParams(businessParams);

        // 设置卖家支付宝用户ID
        model.setSellerId("2088721035348681");

        // 设置商户机具终端编号
        model.setTerminalId("NJ_T_001");

        request.setBizModel(model);

        // 支付完成后自动跳转本地页面的路径
        request.setReturnUrl("http://localhost:8080/?");

        try {
            AlipayTradePrecreateResponse response = alipayClient.execute(request);
            System.out.println(response.getBody());

            String content = response.getQrCode();
            // 将响应的结果返回给浏览器
            if (response.isSuccess()) {
                System.out.println("调用成功");
                // 返回二维码
                if(null != servletResponse) {
                    QRConfigUtil.createCodeToOutputStream(content, servletResponse.getOutputStream());
                }

                // 返回form表单 ---前端页面暂时未正确显示
//                String form = alipayClient.pageExecute(request).getBody();
//                System.out.println("表单页面" + form);
//                servletResponse.setContentType("text/html;charset=" + alipayConfig.getCharset());
//                servletResponse.getWriter().write(form); // 直接将完整的表单输出到页面
//                servletResponse.getWriter().flush();
//                servletResponse.getWriter().close();
            } else {
                System.out.println("调用失败");
                // sdk版本是"4.38.0.ALL"及以上,可以参考下面的示例获取诊断链接
                // String diagnosisUrl = DiagnosisUtils.getDiagnosisUrl(response);
                // System.out.println(diagnosisUrl);
            }
            return content;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 支付宝异步回调
     * @param request
     */
    public void alipayNotify(HttpServletRequest request) {
        Map< String , String > params = new HashMap< String , String >();
        Map requestParams = request.getParameterMap();
        for(Iterator iter = requestParams.keySet().iterator(); iter.hasNext();){
            String name = (String)iter.next();
            String[] values = (String [])requestParams.get(name);
            String valueStr = "";
            for(int i = 0;i < values.length;i ++ ){
                valueStr =  (i==values.length-1)?valueStr + values [i]:valueStr + values[i] + ",";
            }
            //乱码解决，这段代码在出现乱码时使用。
            //valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
            System.out.println(name + ":" + valueStr);
            params.put (name,valueStr);
        }
        //调用SDK验证签名
        //公钥验签示例代码
        try {
            boolean signVerified = AlipaySignature.rsaCheckV1(params, alipayConfig.getAlipayPublicKey(), alipayConfig.getCharset(), alipayConfig.getSignType());
            //公钥证书验签示例代码
            //   boolean flag = AlipaySignature.rsaCertCheckV1(params,alipayPublicCertPath,"UTF-8","RSA2");

            if (signVerified) {
                // TODO 验签成功后
                //按照支付结果异步通知中的描述，对支付结果中的业务内容进行1\2\3\4二次校验，校验成功后在response中返回success

                // 调用orderService修改订单支付状态
                orderService.updateOrderStatus(params.get("out_trade_no"));
            } else {
                // TODO 验签失败则记录异常日志，并在response中返回fail.
            }
        } catch (Exception e) {
            throw new RuntimeException();
        }
    }
}
